/*
* This file is part of washmatique-lib.

* washmatique-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.

* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this library;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

* Copyright (C) 2011 boris Sabadach
* http://washmatique.fr/

*/

package fr.washmatique.spark.components.navigators {


	import flash.events.Event;

	import fr.washmatique.spark.skin.AccordionElementSkin;

	import mx.core.IVisualElement;
	import mx.core.UIComponent;
	import mx.events.ResizeEvent;

	import spark.components.SkinnableContainer;
	import spark.effects.easing.IEaser;
	import spark.layouts.VerticalLayout;


	[SkinState("disabled")]
	[SkinState("folded")]
	[SkinState("normal")]

	/**
	 * Defines a component which purpose is to be used as a direct child of an Accordion component
	 * @see fr.washmatique.spark.components.Accordion
	 * @see fr.washmatique.spark.components.AccordionElementHeader
	 */
	public class AccordionElement extends SkinnableContainer {

		//--------------------------------------------------------------------------
		//
		//  Skin Parts
		//
		//--------------------------------------------------------------------------


		[SkinPart(required="true")]
		public var header:AccordionElementHeader;

		//--------------------------------------------------------------------------
		//
		//  Variables and properties 
		//
		//--------------------------------------------------------------------------
		private var _defaultSkinClass:Class=AccordionElementSkin;

		private var _headerSkinClass:Class;

		private var _maxContentHeight:int;

		private var _opened:Boolean=false;


		private var _headerLabel:String;

		private var _openDuration:uint;

		private var _easer:IEaser;




		public function AccordionElement() {
			super();
		}

		[Bindable]
		public function get easer():IEaser {
			return _easer;
		}

		/**
		 * sets the easer for the animation 
		 * @param value
		 * 
		 */		
		public function set easer(value:IEaser):void {
			if (_easer==value)
				return;
			_easer=value;
		}

		/**
		 * 
		 */		
		[Bindable]
		public function get openDuration():uint {
			return _openDuration;
		}

		/**
		 * the time the element takes to fold or unfold
		 * @param value
		 * 
		 */		
		public function set openDuration(value:uint):void {
			if (_openDuration == value)
				return;
			_openDuration=value;
		}

		override public function initialize():void {
			autoLayout=true;
			setStyle("skinClass", _defaultSkinClass);
			super.initialize();
		}

		/**
		 *
		 * @return the label of the header skin part text
		 *
		 */
		public function get headerLabel():String {
			return _headerLabel;
		}

		public function set headerLabel(value:String):void {
			if (_headerLabel !== value) {
				_headerLabel=value;
			}
		}


		/**
		 * sets the header skin class property
		 * @param value
		 *
		 */
		public function setHeaderSkinClass(value:Class):void {
			_headerSkinClass=value;
		}





		public function set maxContentHeight(value:Number):void {
			_maxContentHeight=value;
		}

		[Bindable]
		/**
		 * the visible height is the height of the first child
		 * @return
		 *
		 */
		public function get maxContentHeight():Number {
			return _maxContentHeight;
		}


		/**
		 * a flag that tells if the element shows its entire content or just the header
		 * @return
		 *
		 */
		public function get opened():Boolean {
			return _opened;
		}

		public function set opened(value:Boolean):void {
			if (_opened == value)
				return;
			_opened=value;
			if (header) {
				header.selected=_opened;
			}

			invalidateSkinState();
		}


		public function setHeaderSwitchability(value:Boolean):void {
			if (header)
				header.switchAble=value;
		}

		//--------------------------------------------------------------------------
		//
		//  Overridden methods
		//
		//--------------------------------------------------------------------------

		/**
		 *  @private
		 */
		override protected function getCurrentSkinState():String {
			return !_opened ? "folded" : "normal";
		}


		/**
		 *  @private
		 */
		override protected function measure():void {
			super.measure();
			var element:IVisualElement=getElementAt(0);
			if (element) {
				maxContentHeight=element.getPreferredBoundsHeight();
			}

		}



		/**
		 *  @private
		 */
		override protected function partAdded(partName:String, instance:Object):void {
			super.partAdded(partName, instance);
			if (instance == header) {
				configureHeader();
				return;
			}

			if (partName == "contentGroup") {
				contentGroup.addEventListener(ResizeEvent.RESIZE, contentGroupChildResizeEventHandler, true, 0, false);
			}

		}



		/**
		 *  @private
		 */
		override protected function partRemoved(partName:String, instance:Object):void {
			super.partRemoved(partName, instance);
			if (partName == "contentGroup") {
				contentGroup.removeEventListener(ResizeEvent.RESIZE, contentGroupChildResizeEventHandler);
			}
		}

		//--------------------------------------------------------------------------
		//
		//  protected and private methods
		//
		//--------------------------------------------------------------------------

		/**
		 * @private
		 *
		 */
		private function configureHeader():void {
			var accordion:Accordion=owner as Accordion;
			header.switchAble=accordion.foldable;
			header.selected=_opened;
			header.enabled=enabled;
			header.owner=this;
			header.label=_headerLabel;
			if (_headerSkinClass) {
				header.setStyle("skinClass", _headerSkinClass);
			}
		}


		/**
		 * @private
		 *
		 */
		private function contentGroupChildResizeEventHandler(evt:ResizeEvent):void {
			var resizedElement:UIComponent=evt.target as UIComponent;

			if (evt.oldHeight < resizedElement.height && _maxContentHeight < resizedElement.height) {
				invalidateSize();
			}

			if (evt.oldHeight > resizedElement.height && _maxContentHeight > resizedElement.height) {
				invalidateSize();
			}
		}


	}
}

